
/*==========================================================================
	NameSpace:	Send
	Purpose: 	Usermessages with size Recording!
				This allows us to make full use of a usermessage buffer.
				Giving almost perfectly optermised usermessages.
==========================================================================*/
if ( SERVER ) then
	local Send = {}
	
	function Send.Start(Name,Player)
		umsg.Start(Name,Player)
		Send.Size = #Name + 2
		Send.Name = Name
		Send.Player = Player
	end
	
	function Send.Restart()
		umsg.Char(0) --We end the loop!
		umsg.End()
		Send.Start(Send.Name,Send.Player)
	end
	
	function Send.End()
		umsg.Char(0)
		umsg.End()
		Send.Player = nil
	end
	
	function Send.CheckSize(N)
		return Send.Size + (N || 0) >= 255
	end
	
	function Send.AutoRestart(N)
		if ( Send.CheckSize(0 + (N || 0)) ) then
			Send.Restart()
		end
	end
	
	function Send.Char(N)
		umsg.Char(N)
		Send.Size = Send.Size + 1
	end
	
	function Send.Bool(B)
		umsg.Short(B)
		Send.Size = Send.Size + 1
	end
	
	function Send.Short(N)
		umsg.Short(N)
		Send.Size = Send.Size + 2
	end
	
	function Send.Long(N)
		umsg.Long(N)
		Send.Size = Send.Size + 4
	end
	
	function Send.Float(N)
		umsg.Float(N)
		Send.Size = Send.Size + 4
	end
	
	function Send.String(S)
		umsg.String(S)
		Send.Size = Send.Size + #S + 1
	end
	
	function Send.Entity(E)
		umsg.Entity(E)
		Send.Size = Send.Size + 4
	end
	
	
/*==========================================================================
	Name:	WPP.SyncEntitys
	Purpose: 	Syncs a list of entitys with a client
==========================================================================*/
	function WPP:SyncEntitys(T,Player)
		Send.Start("WPP_ES",Player)
		
		for _,Entity in pairs ( T ) do
			
			if ( Entity.WPP ) then
				
				--Send the entity!
				Send.Char(1)
				Send.Entity(Entity)
				Send.AutoRestart()
				
				--Send the owner
				Send.Char(2)
				Send.String(Entity.WPP.Owner)
				Send.AutoRestart()
				
				--Send the owners name
				Send.Char(3)
				Send.String(Entity.WPP.Name)
				
				--Send the Age
				Send.Char(4)
				Send.Float(Entity:WPP_Age())
				Send.AutoRestart()
				
				--Send Colide Type
				Send.Char(5)
				Send.Char(Entity.WPP.Collide)
				Send.AutoRestart()
				
				
				
				--Share Touch
				Send.Char(6)
				Send.Bool(Entity.WPP.Share.Touch)
				Send.AutoRestart()
				
				--Share Grab
				Send.Char(7)
				Send.Bool(Entity.WPP.Share.Grab)
				Send.AutoRestart()
				
				--Share Tool
				Send.Char(8)
				Send.Bool(Entity.WPP.Share.Tool)
				Send.AutoRestart()
				
				--Share Use
				Send.Char(9)
				Send.Bool(Entity.WPP.Share.Use)
				Send.AutoRestart()
				
				--Share Remove
				Send.Char(10)
				Send.Bool(Entity.WPP.Share.Remove)
				Send.AutoRestart()
				
				--Share Duplicate
				Send.Char(11)
				Send.Bool(Entity.WPP.Share.Duplicate)
				Send.AutoRestart()
				
				--Share Damage
				Send.Char(12)
				Send.Bool(Entity.WPP.Share.Damage)
				Send.AutoRestart()
				
				--Share Noclip
				Send.Char(13)
				Send.Bool(Entity.WPP.Share.Noclip)
				Send.AutoRestart()
				
				--Share CPPI
				Send.Char(14)
				Send.Bool(Entity.WPP.Share.CPPI)
				Send.AutoRestart()
				
				--Used
				Send.Char(15)
				Send.Bool(Entity.WPP.Used)
				Send.AutoRestart()
				
				
			end
		end
		
		Send.End()
	end
	
/*==========================================================================
	Name:		WPP.SyncTrust
	Purpose: 	Syncs the trust list
==========================================================================*/	
	function WPP:SyncTrust(Player)
		Send.Start("WPP_TS",Player)
			
			for Trust,Bool in pairs ( WPP.TrustTable ) do
				if ( Trust:find(Player:UniqueID(),1,true) ) then
					Send.AutoRestart(#Trust + 2)
					Send.Char(Bool and 1 or 2)
					Send.String(Trust)
				end
			end
		
		Send.End()
	end

/*==========================================================================
	Section: Usermesage String Pools!
==========================================================================*/	
	umsg.PoolString("WPP_ES") --Entity Sync
	umsg.PoolString("WPP_TS") --Trust Sync
	umsg.PoolString("WPP_ST") --Set Trust
	umsg.PoolString("WPP_SG") --Set Global
	umsg.PoolString("WPP_SO") --Set Owner
	umsg.PoolString("WPP_SC") --Set Colide
	
	
else 


/*==========================================================================
	usermessage:	"WPP_ES"
	Purpose: 		Syncs the entity list
==========================================================================*/	
	local E
	usermessage.Hook("WPP_ES",function(um)
		
		local AntInf = 0
		local Char = um:ReadChar()
		while ( true ) do
			
			if ( Char == 0 ) or ( AntInf >= 100 ) then 
				break --end the UMSG
				
			elseif ( Char == 1 ) then
				local Ent = um:ReadEntity()
				if ( Ent ) and ( Ent:IsValid() ) then
					E = Ent
					E.WPP = E.WPP || {}
					E.WPP.Share = E.WPP.Share || {}
				end
				
			elseif ( E ) and ( Char == 2 ) then
				E.WPP.Owner = um:ReadString()
				E.WPP.Owned = true
				
			elseif ( E ) and ( Char == 3 ) then
				E.WPP.Name = um:ReadString()
				
			elseif ( E ) and ( Char == 4 ) then
				E.WPP.Time = CurTime() - um:ReadFloat()
				
			elseif ( E ) and ( Char == 5 ) then
				E.WPP.Collide = um:ReadChar()
				
			elseif ( E ) and ( Char == 6 ) then
				E.WPP.Share.Touch = um:ReadBool()
				
			elseif ( E ) and ( Char == 6 ) then
				E.WPP.Share.Grab = um:ReadBool()
				
			elseif ( E ) and ( Char == 7 ) then
				E.WPP.Share.Tool = um:ReadBool()
				
			elseif ( E ) and ( Char == 9 ) then
				E.WPP.Share.Use = um:ReadBool()
				
			elseif ( E ) and ( Char == 10 ) then
				E.WPP.Share.Remove = um:ReadBool()
				
			elseif ( E ) and ( Char == 11 ) then
				E.WPP.Share.Duplicate = um:ReadBool()
				
			elseif ( E ) and ( Char == 12 ) then
				E.WPP.Share.Damage = um:ReadBool()
				
			elseif ( E ) and ( Char == 13 ) then
				E.WPP.Share.Noclip = um:ReadBool()
				
			elseif ( E ) and ( Char == 14 ) then
				E.WPP.Share.CPPI = um:ReadBool()
			
			elseif ( E ) and ( Char == 15 ) then
				E.WPP.Used = um:ReadBool()
			end
			
			local Char = um:ReadChar() || 0
			AntInf = AntInf + 1
		end
	
	end)


/*==========================================================================
	usermessage:	"WPP_TS"
	Purpose: 		Syncs the trust list
==========================================================================*/	
	usermessage.Hook("WPP_TS",function(um)
		local AntInf = 0
		local Char = um:ReadChar()
		
		while ( true ) do
			
			if ( Char == 0 ) or ( AntInf >= 100 ) then
				break
				
			elseif ( Char == 1 ) then
				WPP.TrustTable[ um:ReadString() ] = true
			
			elseif ( Char == 2 ) then
				WPP.TrustTable[ um:ReadString() ] = nil
			end
			
			Char = um:ReadChar() || 0
			AntInf = AntInf + 1
		end
		
	end)
	
/*==========================================================================
	usermessage:	"WPP_ST"
	Purpose: 		Calls Set Trust Hook
==========================================================================*/	
	usermessage.Hook("WPP_ST",function(um)
		hook.Call("WPP_SetTrust",GAMEMODE,
			um:ReadEntity(),
			um:ReadEntity(),
			um:ReadString(),
			um:ReadBool())
	end)
	

	
/*==========================================================================
	usermessage:	"WPP_SG"
	Purpose: 		Calls Set Global Hook
==========================================================================*/	
	usermessage.Hook("WPP_SG",function(um)
		hook.Call("WPP_SetGlobal",GAMEMODE,
			um:ReadEntity(),
			um:ReadString(),
			um:ReadBool())
	end)
	
/*==========================================================================
	usermessage:	"WPP_SO"
	Purpose: 		Calls Set Owner Hook
==========================================================================*/	
	usermessage.Hook("WPP_SO",function(um)
		hook.Call("WPP_SetOwner",GAMEMODE,
			um:ReadEntity(),
			um:ReadEntity())
	end)
	
/*==========================================================================
	usermessage:	"WPP_SC"
	Purpose: 		Calls Set Colide Hook
==========================================================================*/	
	usermessage.Hook("WPP_SC",function(um)
		hook.Call("WPP_SetColide",GAMEMODE,
			um:ReadEntity(),
			um:ReadChar())
	end)
end


--Unused?
//usermessage.Hook("WPP_TrustKey",function(um) WPP.TrustTable[ um:ReadString() ] = um:ReadBool() end)